﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using OxyPlot.Series;

namespace DesigneSpaceExplorerVEGA
{
    public class Hypervolume
    {

        #region Constructors

        public Hypervolume()
        {

        }

        #endregion

        #region Members
        #endregion

        #region Properties
        public List<ScatterPoint> Input { get; set; }
        public double Output { get; private set; }

        public List<ScatterPoint> Pareto { get; private set; }

        public ScatterPoint ExtremisPoint { get; private set; }

        #endregion

        #region Public Methods

        public void Compute()
        {
            var points = new List<ScatterPoint>();

            double maxX = 0;
            double maxY = 0;

            foreach (ScatterPoint point in Input)
            {
                var isDominanted = Input.Any(t => point.X > t.X && point.Y > t.Y);
                if (!isDominanted)
                {
                    points.Add(point);
                }
                maxX = point.X > maxX ? point.X : maxX;
                maxY = point.Y > maxY ? point.Y : maxY;
            }

            points.Sort(new PointComparer());

            double hypervolume = 0;

            for (int i = 0; i < points.Count - 1; i++)
            {
                var first = new ScatterPoint(points[i].X, points[i].Y);
                var last = new ScatterPoint(points[i + 1].X, points[i + 1].Y);
                var height = maxY - first.Y;
                var width = last.X - first.X;
                hypervolume += (width * height);
            }

            var pct = new ScatterPoint(points[points.Count - 1].X, points[points.Count - 1].Y);
            var h = maxY - pct.Y;
            var w = maxX - pct.X;
            hypervolume += (w * h);

            Output = hypervolume;
            Pareto = new List<ScatterPoint>();
            Pareto.Add(new ScatterPoint(points[0].X, maxY));
            Pareto.AddRange(points);
            Pareto.Add(new ScatterPoint(maxX, points[points.Count-1].Y));

            ExtremisPoint = new ScatterPoint(maxX,maxY);
        }

        #endregion

        #region Private Methods
        #endregion

        
    }
}
